﻿using Activity.Comm;
using Activity.Data;
using Activity.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Configuration;
using static Activity.Helper.CommHelper;

namespace Activity.API
{
    /// <summary>
    /// 处理新年领取红包类
    /// </summary>
    public class HappyNewYearHandler
    {
        /// <summary>
        /// 领取开始时间
        /// </summary>
        static readonly DateTime beginDate = new DateTime(2018, 2, 14, 0, 0, 0);
        /// <summary>
        /// 领取结束时间
        /// </summary>
        static readonly DateTime endDate = new DateTime(2018, 2, 21, 23, 59, 59);
        /// <summary>
		/// 使用的Redis数据库索引
		/// </summary>
		public const int RedisDatabaseIndex = 4;
        /// <summary>
        /// 测试
        /// </summary>
        static readonly string isDebug = WebConfigurationManager.AppSettings["isDebug"];
        /// <summary>
        /// 测试
        /// </summary>
        static readonly string isBeginTime = WebConfigurationManager.AppSettings["isBeginTime"];
        /// <summary>
        /// redis保持红包的缓存Key
        /// </summary>
        string redisKey = "HappyNewYearRedPac";
        /// <summary>
        /// redis记录页的浏览次数Key
        /// </summary>
        string redisPageBrowseNum = "keyword" + DateTime.Now.ToString("yyyyMMdd");
        /// <summary>
        /// redis记录非会员的扫码数Key
        /// </summary>
        string redisNoMemberPageNum = "NoMemberPageNum";

        private static object obj = new object();
        /// <summary>
        /// 领取红包
        /// </summary>
        /// <param name="openID"></param>
        /// <returns></returns>
        public Messages GetCollarRed(string OpenId = "")
        {
            try
            {
                if (string.IsNullOrWhiteSpace(OpenId)) return new Messages { IsSuc = false, Code = -1, Message = "无效的OPENID" };
                if (DateTime.Now < beginDate && isDebug.ToLower() == "false" && isBeginTime.ToLower() == "false")
                {
                    return new Messages { IsSuc = false, Code = -1, Message = "亲，活动还没开始呢" };
                }
                if (DateTime.Now >= endDate && isDebug.ToLower() == "false" && isBeginTime.ToLower() == "false")
                {
                    return new Messages { IsSuc = false, Code = -1, Message = "亲，活动已经结束了" };
                }
                if (IsDayCollarRed(OpenId) && isDebug.ToLower() == "false")
                {
                    return new Messages { IsSuc = true, Code = 0, Message = "亲，今天您已经领过红包了，欢迎明天再来！" };
                }

                try
                {
                    int CardType = 0;
                    //领取先锁住
                    lock (obj)
                    {
                        //var rc = new RedisClient(RedisDatabaseIndex);
                        //if (rc.KeyExists(redisKey))
                        //{
                        //    rc.RemoveKey(redisKey);
                        //}

                        CardType = GetCardType();
                        //恒康ERP相关的获取保存卡编号操作
                        string CardCode = GetTHQID(CardType);
                        string THQNo = GetTHQNo();
                        SaveRedPacHKERP(OpenId, CardCode, CardType, THQNo);
                        AddRedPacLog(OpenId, THQNo, CardType);
                    }
                    return new Messages { IsSuc = true, Code = CardType, Message = CardType.ToString() };
                }
                catch (Exception ex)
                {
                    Log.Error(ex);
                    return new Messages { IsSuc = false, Code = -1, Message = ex.Message };
                }
            }
            catch (Exception ex)
            {
                Log.Error("领取红包异常:" + ex);
                return new Messages { IsSuc = false, Code = -1, Message = "领取红包异常" };
            }
        }

        /// <summary>
        /// 清空红包和浏览数redis缓存
        /// </summary>
        public void RemoverRedNum()
        {
            var rc = new RedisClient(RedisDatabaseIndex);
            if (rc.KeyExists(redisKey)) 
            {
                rc.RemoveKey(redisKey);
            }

            //清空活动开始前的所以浏览记录数
            DateTime dtStartDate = Convert.ToDateTime("2018-01-22");
            DateTime dtEndDate = Convert.ToDateTime("2018-02-13");
            string strKey = "keyword" + dtStartDate.ToString("yyyyMMdd");
            if (rc.KeyExists(strKey))
            {
                rc.RemoveKey(strKey);
            }
            TimeSpan ts = dtEndDate - dtStartDate;
            for (int i = 1; i <= ts.Days; i++)
            {
                strKey = "keyword" + dtStartDate.AddDays(i).ToString("yyyyMMdd");
                if (rc.KeyExists(strKey))
                {
                    rc.RemoveKey(strKey);
                }
            }

            if (rc.KeyExists(redisNoMemberPageNum))
            {
                rc.RemoveKey(redisNoMemberPageNum);
            }
        }

        /// <summary>
        /// 检查用户是否注册
        /// </summary>
        /// <param name="openID"></param>
        /// <returns></returns>
        public Messages CheckUser(string openID)
        {
            try
            {
                bool bol = false;
                using (var dc = new HKEntities())
                {
                    bol = dc.KM_V_CardBinding.Any(t => t.OpenID == openID);
                };
                if (bol)
                {
                    //已注册，是否抽奖。
                    if (IsDayCollarRed(openID) && isDebug.ToLower() == "false")
                    {
                        return new Messages { IsSuc = true, Code = 1, Message = "亲，今天您已经领过红包了，欢迎明天再来！" };
                    }
                    else
                    {
                        return new Messages { IsSuc = true, Code = 0, Message = openID };
                    }
                }
                else
                {
                    //直接返回
                    NoMemberPageNum();
                    return new Messages { IsSuc = false, Code = -4, Message = "请先注册会员" };
                }
            }
            catch (Exception ex)
            {
                Log.Error("检查用户是否注册:" + ex);
                return new Messages { IsSuc = false, Code = -1, Message = ex.Message };
            }
        }

        /// <summary>
        /// 返回新年统计结果实体类
        /// </summary>
        /// <returns></returns>
        public CountNum HappyNewYearCount(string StartDate,string EndDate)
        {
            if (string.IsNullOrEmpty(StartDate))
            {
                return new CountNum { IsSuc = false, Message = "开始时间不能为空！" };
            }
            if (string.IsNullOrEmpty(EndDate))
            {
                return new CountNum { IsSuc = false, Message = "结束时间不能为空！" };
            }

            try
            {
                DateTime dtStartDate = Convert.ToDateTime(Convert.ToDateTime(StartDate).ToString("yyyy-MM-dd"));
                DateTime dtEndDate = Convert.ToDateTime(Convert.ToDateTime(EndDate).ToString("yyyy-MM-dd"));
                if (dtStartDate > dtEndDate)
                {
                    return new CountNum { IsSuc = false, Message = "开始时间不能大于结束时间" };
                }
                int PageNum = 0;
                if (dtStartDate == dtEndDate)
                {
                    string strKey = "keyword" + dtStartDate.ToString("yyyyMMdd");
                    PageNum = GetPageNum(strKey);
                }
                else
                {
                    string strKey = "keyword" + dtStartDate.ToString("yyyyMMdd");
                    PageNum = GetPageNum(strKey);
                    TimeSpan ts = dtEndDate - dtStartDate;
                    for (int i = 1; i <= ts.Days; i++)
                    {
                        strKey = "keyword" + dtStartDate.AddDays(i).ToString("yyyyMMdd");
                        PageNum += GetPageNum(strKey);
                    }
                }
                int NoMemberPageNum = GetPageNum(redisNoMemberPageNum);

                string strStartDate = dtStartDate.ToString("yyyy-MM-dd");
                string strEndDate = dtEndDate.ToString("yyyy-MM-dd") + " 23:59:59";
                int TenYuanNum = 0;
                int TwentyYuanNum = 0;
                int SixtyYuanNum = 0;
                int ReceiveNum = 0;
                int UseNum = 0;
                decimal OutAmount = 0;
                using (var dc = new ActivityEntities())
                {
                    string TenYuanNumSql = string.Format(@"SELECT COUNT(1) AS TenYuanNum FROM [dbo].[KM_HappyNewYearLog] WHERE CardType=1 AND ReceiveTime>='{0}' AND ReceiveTime<='{1}' ", strStartDate, strEndDate);
                    TenYuanNum = dc.Database.SqlQuery<int>(TenYuanNumSql).FirstOrDefault();
                    string TwentyYuanNumSql = string.Format(@"SELECT COUNT(1) AS TenYuanNum FROM [dbo].[KM_HappyNewYearLog] WHERE CardType=2 AND ReceiveTime>='{0}' AND ReceiveTime<='{1}' ", strStartDate, strEndDate);
                    TwentyYuanNum = dc.Database.SqlQuery<int>(TwentyYuanNumSql).FirstOrDefault();
                    string SixtyYuanNumSql = string.Format(@"SELECT COUNT(1) AS TenYuanNum FROM [dbo].[KM_HappyNewYearLog] WHERE CardType=3 AND ReceiveTime>='{0}' AND ReceiveTime<='{1}' ", strStartDate, strEndDate);
                    SixtyYuanNum = dc.Database.SqlQuery<int>(SixtyYuanNumSql).FirstOrDefault();

                    string ReceiveNumSql = string.Format(@"SELECT COUNT(1) AS ReceiveNum FROM [dbo].[KM_HappyNewYearLog] WHERE 1=1 AND ReceiveTime>='{0}' AND ReceiveTime<='{1}' ", strStartDate, strEndDate);
                    ReceiveNum = dc.Database.SqlQuery<int>(ReceiveNumSql).FirstOrDefault();
                    string UseNumSql = string.Format(@"SELECT COUNT (1) AS UseNum FROM [dbo].[KM_HappyNewYearLog] AS A
INNER JOIN KMERPQueryDB.HKERP.dbo.Crm_Bas_THQDetail AS B
ON B.WXOpenID=A.OpenId AND B.THQNo=A.CardCode AND THQStatus=2 
WHERE 1=1 
AND A.ReceiveTime>='{0}' AND A.ReceiveTime<='{1}'
AND B.UseStartDate>='{0}' AND B.UseStartDate<='{1}' ", strStartDate, strEndDate);
                    UseNum = dc.Database.SqlQuery<int>(UseNumSql).FirstOrDefault();
                    string OutAmountSql = string.Format(@"SELECT COALESCE(SUM(CASE WHEN CardType=1 THEN 10 ELSE (CASE WHEN CardType=2 THEN 20 ELSE (CASE WHEN CardType=3 THEN 66.6 ELSE 0 END) END) END),0) AS OutAmount 
FROM [dbo].[KM_HappyNewYearLog] 
WHERE 1=1 AND ReceiveTime>='{0}' AND ReceiveTime<='{1}'", strStartDate, strEndDate);
                    OutAmount = dc.Database.SqlQuery<decimal>(OutAmountSql).FirstOrDefault();
                };

                return new CountNum { IsSuc = true, PageNum = PageNum, NoMemberPageNum = NoMemberPageNum, TenYuanNum = TenYuanNum, TwentyYuanNum = TwentyYuanNum, SixtyYuanNum = SixtyYuanNum, ReceiveNum = ReceiveNum, UseNum = UseNum, OutAmount = OutAmount };
            }
            catch (Exception ex)
            {
                return new CountNum { IsSuc = false, Message = ex.Message };
            }
        }

        /// <summary>
        /// 根据Key取出每天的流量数
        /// </summary>
        /// <param name="redisPageKey"></param>
        /// <returns></returns>
        public int GetPageNum(string redisPageKey)
        {
            var rc = new RedisClient(RedisDatabaseIndex);
            if (!rc.KeyExists(redisPageKey))
            {
                //流量缓存Key不存在直接返回 0
                return 0;
            }
            return rc.GetInt(redisPageKey);
        }

        /// <summary>
        /// 返回新年统计结果
        /// </summary>
        public class CountNum
        {
            /// <summary>
            /// 响应成功与失败标识 true:成功 false:失败
            /// </summary>
            public bool IsSuc { get; set; }
            /// <summary>
            /// IsSuc=false 有错误描述
            /// </summary>
            public string Message { get; set; }
            /// <summary>
            /// 扫描累计数
            /// </summary>
            public int PageNum { get; set; }
            /// <summary>
            /// 非会员的扫描累计数
            /// </summary>
            public int NoMemberPageNum { get; set; }
            /// <summary>
            /// 10元领取数
            /// </summary>
            public int TenYuanNum { get; set; }
            /// <summary>
            /// 20元领取数
            /// </summary>
            public int TwentyYuanNum { get; set; }
            /// <summary>
            /// 66.6元领取数
            /// </summary>
            public int SixtyYuanNum { get; set; }
            /// <summary>
            /// 红包领取数
            /// </summary>
            public int ReceiveNum { get; set; }
            /// <summary>
            /// 红包使用数
            /// </summary>
            public int UseNum { get; set; }
            /// <summary>
            /// 红包发放总金额
            /// </summary>
            public decimal OutAmount { get; set; }
        }

        /// <summary>
        /// 保存已领红包系统日志
        /// </summary>
        /// <param name="OpenId">OpenId</param>
        /// <param name="CardCode">红包卡编号</param>
        /// <param name="CardType">红包类型</param>
        public void AddRedPacLog(string OpenId, string CardCode, int CardType)
        {
            try
            {
                using (var dc = new ActivityEntities())
                {
                    var addLog = new KM_HappyNewYearLog
                    {
                        SID = Guid.NewGuid().ToString(),
                        OpenId = OpenId,
                        CardCode = CardCode,
                        CardType = CardType,
                        ReceiveTime = DateTime.Now,
                        ActivityType = 1
                    };
                    dc.KM_HappyNewYearLog.Add(addLog);
                    dc.SaveChanges();
                };
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 根据红包类型获取三种红包的固定ERP内码
        /// </summary>
        /// <param name="CardType">卷类型：1=10、2=20、3=66.6</param>
        /// <returns></returns>
        public string GetTHQID(int CardType)
        {
            string THQID = string.Empty;
            if (CardType == 2)
            {
                THQID = "KM000076";
            }
            else if (CardType == 3)
            {
                THQID = "KM000077";
            }
            else
            {
                THQID = "KM000073";
            }
            return THQID;
        }
        /// <summary>
        /// 获取券号，14位，含数字字母随机生成，建议KM开头
        /// </summary>
        /// <returns>指定长度的随机字符串</returns>
        public string GetTHQNo()
        {
            string strSep = ",";
            char[] chrSep = strSep.ToCharArray();
            string strChar = "0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z";
            string[] aryChar = strChar.Split(chrSep, strChar.Length);
            string strRandom = string.Empty;

            var Rnd = new Random((int)DateTime.Now.Ticks);
            //生成随机字符串
            for (int i = 0; i < 12; i++)
            {
                strRandom += aryChar[Rnd.Next(aryChar.Length)];
            }
            return "KM" + strRandom;
        }
        /// <summary>
        /// 把生成的红包卡券保存到恒康ERP库
        /// </summary>
        /// <param name="OpenId">微信对应用户唯一OpenId</param>
        /// <param name="CardCode">CardCode=红包卡编号=三种金额的优惠券对应固定的ERP内码</param>
        /// <param name="CardType">卷类型：1=10、2=20、3=66.6</param>
        public void SaveRedPacHKERP(string OpenId, string CardCode, int CardType,string THQNo)
        {
            try
            {
                string BillNo = "THQPr" + DateTime.Now.ToString("yyMMdd") + "KM01-001";
                using (var dc = new HKEntities())
                {
                    var query = dc.KM_V_CardBinding.FirstOrDefault(t => t.OpenID == OpenId);
                    string CustomerID = query.CustomerID;
                    string THQID = CardCode;
                    DateTime UseStartDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd"));
                    DateTime UseEndDate = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd") + " 23:59:59");
                    decimal Amount = 0;
                    if (CardType == 2)
                    {
                        Amount = 20;
                    }
                    else if (CardType == 3)
                    {
                        Amount = Convert.ToDecimal(66.6);
                    }
                    else
                    {
                        Amount = 10;
                    }

                    //var addTHQDetail = new Crm_Bas_THQDetail
                    //{
                    //    CompanyID = "KM",
                    //    BillNo = BillNo,
                    //    CustomerID = CustomerID,
                    //    THQID = THQID,
                    //    UseStartDate = UseStartDate,
                    //    UseEndDate = UseEndDate,
                    //    MiniAmounts = Amount,
                    //    Amount = Amount,
                    //    THQNo = THQNo,
                    //    THQStatus = "1",
                    //    PromoteTypeID = "0",
                    //    WXPublicNo = "",
                    //    WXOpenID = OpenId,
                    //    PromoteDate = DateTime.Now,
                    //    PromoteState = "0",
                    //    ModifyDTM = DateTime.Now,
                    //    Sequence = "",
                    //    BillTypeID = "Crm_CardRegDef",
                    //    THQRuleType = "1",
                    //    OldCustomerID = null,
                    //    StatusRemark = null,
                    //    PromoteUserID = null,
                    //    ISWX_HK = null
                    //    //SaleShopID = null
                    //};
                    //dc.Crm_Bas_THQDetail.Add(addTHQDetail);
                    //dc.SaveChanges();

                    string insertSql = @"INSERT INTO [dbo].[Crm_Bas_THQDetail]
           ([CompanyID]
           ,[BillNo]
           ,[CustomerID]
           ,[THQID]
           ,[UseStartDate]
           ,[UseEndDate]
           ,[MiniAmounts]
           ,[Amount]
           ,[THQNo]
           ,[THQStatus]
           ,[PromoteTypeID]
           ,[WXPublicNo]
           ,[WXOpenID]
           ,[PromoteDate]
           ,[PromoteState]
           ,[ModifyDTM]
           ,[Sequence]
           ,[BillTypeID]
           ,[THQRuleType]
           ,[OldCustomerID]
           ,[StatusRemark]
           ,[PromoteUserID]
           ,[ISWX_HK])
     VALUES
           ('KM','{0}','{1}','{2}','{3}','{4}',{5},{6},'{7}','1','0','','{8}',GETDATE(),'0',GETDATE(),'','Crm_CardRegDef','1',null,null,null,null) ";
                    insertSql = string.Format(insertSql, BillNo, CustomerID, THQID, UseStartDate, UseEndDate, Amount, Amount, THQNo, OpenId);
                    var insertNum = dc.Database.ExecuteSqlCommand(insertSql);
                };
                
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
        /// <summary>
        /// 获取抽中的卡类型 1、2、3
        /// </summary>
        /// <returns></returns>
        public int GetCardType()
        {
            var rc = new RedisClient(RedisDatabaseIndex);
            if (!rc.KeyExists(redisKey))
            {
                //抽完后继续初始化奖池
                InitPrizePool();
            }

            var random = new Random((int)DateTime.Now.Ticks);
            var values = 0;
            var _newval = 88;

            var PoolLength = rc.GetListLength(redisKey);
            var resultNum = random.Next((int)PoolLength) - 1;
            values = rc.GetIntFromList(redisKey, resultNum);
            rc.SetIntToList(redisKey, resultNum, _newval);
            rc.RemoveStringFromList(redisKey, _newval.ToString());
            return values;
        }
        /// <summary>
        /// 根据OpenID判断当天是否以领红包
        /// </summary>
        /// <param name="openID"></param>
        /// <returns></returns>
        public bool IsDayCollarRed(string openID)
        {
            bool bol = false;
            using (var dc = new ActivityEntities())
            {
                string strDayTime = DateTime.Now.ToString("yyyy-MM-dd");
                string strDayTimeEnd = strDayTime + " 23:59:59";
                DateTime dtDayTime = Convert.ToDateTime(strDayTime);
                DateTime dtDayTimeEnd = Convert.ToDateTime(strDayTimeEnd);
                if (dc.KM_HappyNewYearLog.Any(t => t.OpenId == openID && t.ReceiveTime >= dtDayTime && t.ReceiveTime <= dtDayTimeEnd))
                {
                    bol = true;
                }
            };
            return bol;
        }

        /// <summary>
        /// 初始化奖池写入到redis
        /// </summary>
        public void InitPrizePool()
        {
            var rc = new RedisClient(RedisDatabaseIndex);
            var ListInitData = InitData();
            if (ListInitData != null)
            {
                foreach (var item in ListInitData)
                {
                    rc.RemoveKey(item.DrawDay);
                    rc.AddIntToList(item.DrawDay, item.RedPacArray);
                }
            }
            //Log.WriteLog("初始化奖池时间:" + DateTime.Now);
        }

        /// <summary>
        /// 记录页的浏览次数写入到redis
        /// </summary>
        public void PageBrowseNumber()
        {
            var rc = new RedisClient(RedisDatabaseIndex);
            if (!rc.KeyExists(redisPageBrowseNum))
            {
                rc.SetInt(redisPageBrowseNum, 1);
            }
            else
            {
                int num = rc.GetInt(redisPageBrowseNum);
                rc.SetInt(redisPageBrowseNum, num + 1);
            }
        }
        /// <summary>
        /// 记录非会员的页面浏览次数写入到redis
        /// </summary>
        public void NoMemberPageNum()
        {
            var rc = new RedisClient(RedisDatabaseIndex);
            if (!rc.KeyExists(redisNoMemberPageNum))
            {
                rc.SetInt(redisNoMemberPageNum, 1);
            }
            else
            {
                int num = rc.GetInt(redisNoMemberPageNum);
                rc.SetInt(redisNoMemberPageNum, num + 1);
            }
        }

        /// <summary>
        /// 初始化奖池
        /// </summary>
        /// <returns></returns>
        public List<RedPacketDataItem> InitData()
        {
            try
            {
                var list = new List<RedPacketDataItem>();
                var data = new RedPacketDataItem();
                int[] RedPacPool = new int[1000];
                RedPacPool = GeneratePool();
                //输出数组类型
                ArrayItem<int> disrupter = new ArrayItem<int>(RedPacPool);
                //输出一个打乱后数组
                data.DrawDay = redisKey;
                data.RedPacArray = disrupter.GetDisruptedItems();
                list.Add(data);
                return list;
            }
            catch (Exception ex)
            {
                Log.Error("奖池初始化错误：" + ex.Message);
            }
            return null;
        }
        /// <summary>
        /// 每次创建200个红包80个10元的、119个20元的、1个66.6元的
        /// </summary>
        /// <returns></returns>
        public int[] GeneratePool()
        {
            int[] RedPacPool = new int[1000];
            for (int i = 0; i < RedPacPool.Length; i++)
            {
                if (i < 400)
                {
                    RedPacPool[i] = (int)CardType.TenYuan;
                }
                else if (i==999)
                {
                    RedPacPool[i] = (int)CardType.SixtyYuan;
                }
                else
                {
                    RedPacPool[i] = (int)CardType.TwentyYuan;
                }
            }
            return RedPacPool;
        }
        /// <summary>
        /// 红包集合实体类
        /// </summary>
        public class RedPacketDataItem
        {
            /// <summary>
            /// 缓存标识
            /// </summary>
            public string DrawDay { get; set; }
            /// <summary>
            /// 红包数组
            /// </summary>
            public int[] RedPacArray { get; set; }
        }
        /// <summary>
        /// 红包类型枚举
        /// </summary>
        public enum CardType
        {
            /// <summary>
            /// 10元红包
            /// </summary>
            TenYuan = 1,
            /// <summary>
            /// 20十元红包
            /// </summary>
            TwentyYuan = 2,
            /// <summary>
            /// 66.6元红包
            /// </summary>
            SixtyYuan = 3
        }

    }
}
